const express = require('express');
const http = require('http');
const next = require('next');
const { Server } = require('socket.io');


// 设置开发模式
const dev = process.env.NODE_ENV !== 'production';

// 初始化 Next.js 应用
const nextApp = next({ dev });

// 获取 Next.js 请求处理器
const nextHandler = nextApp.getRequestHandler();

// 设置监听的主机和端口
const host = process.env.HOST || '0.0.0.0'; // 默认监听所有网络接口
const port = parseInt(process.env.PORT || '3000', 10); // 默认端口为 3000



// 内存存储用户、消息和关系数据（实际应用中应使用数据库）
const users = new Map(); // 用户信息存储
const messages = new Map(); // 消息存储
const privateChats = new Map(); // 一对一聊天记录
const groupChats = new Map(); // 群聊记录
const friendships = new Map(); // 好友关系
const friendRequests = new Map(); // 好友请求
const groups = new Map(); // 群组信息
const groupMembers = new Map(); // 群组成员

// 初始化一些测试数据
function initTestData() {
  // 添加测试用户
  users.set('user1', { id: 'user1', username: '小爱', avatar: '/avatars/avatar1.svg', online: false });
  users.set('user2', { id: 'user2', username: '妮妮', avatar: '/avatars/avatar3.svg', online: false });
  users.set('user3', { id: 'user3', username: '风间', avatar: '/avatars/avatar1.svg', online: false });
  
  // 创建测试群组
  const groupId = 'group1';
  groups.set(groupId, { id: groupId, name: '春日部防卫队', avatar: '/avatars/avatar2.svg', createdBy: 'user1' });
  
  // 添加群组成员
  groupMembers.set(groupId, ['user1', 'user2', 'user3']);
  
  // 添加好友关系
  if (!friendships.has('user1')) friendships.set('user1', []);
  if (!friendships.has('user2')) friendships.set('user2', []);
  if (!friendships.has('user3')) friendships.set('user3', []);
  
  friendships.get('user1').push('user2', 'user3');
  friendships.get('user2').push('user1');
  friendships.get('user3').push('user1');
  
  // 添加一些测试消息
  const chat1 = 'user1_user2'; // 小爱和妮妮的聊天
  const chat2 = 'user1_user3'; // 小爱和风间的聊天
  
  if (!privateChats.has(chat1)) privateChats.set(chat1, []);
  if (!privateChats.has(chat2)) privateChats.set(chat2, []);
  if (!groupChats.has(groupId)) groupChats.set(groupId, []);
  
  // 添加私聊消息
  privateChats.get(chat1).push(
    { id: '1', sender: 'user1', receiver: 'user2', content: '小新睡下，小爱稍后就到', timestamp: Date.now() - 3600000 },
    { id: '2', sender: 'user2', receiver: 'user1', content: '我先去逛美食街啦，你到了联系我', timestamp: Date.now() - 1800000 }
  );
  
  privateChats.get(chat2).push(
    { id: '3', sender: 'user3', receiver: 'user1', content: '哈哈哈哈哈哈', timestamp: Date.now() - 7200000 }
  );
  
  // 添加群聊消息
  groupChats.get(groupId).push(
    { id: '4', sender: 'user1', groupId, content: '大家好', timestamp: Date.now() - 86400000 },
    { id: '5', sender: 'user2', groupId, content: '今晚有派对哦~', timestamp: Date.now() - 43200000 }
  );
}

nextApp.prepare().then(() => {
  const app = express();
  const server = http.createServer(app);
  const io = new Server(server);
  
  // 初始化测试数据
  initTestData();
  
  // 用户连接处理
  io.on('connection', (socket) => {
    console.log('用户已连接:', socket.id);
    let currentUser = null;
    
    // 用户登录
    socket.on('login', ({ userId }) => {
      // 在实际应用中，这里应该有身份验证逻辑
      if (users.has(userId)) {
        currentUser = users.get(userId);
        currentUser.online = true;
        currentUser.socketId = socket.id;
        
        // 将用户加入到自己的房间
        socket.join(userId);
        
        // 获取用户的群组并加入相应的房间
        for (const [groupId, members] of groupMembers.entries()) {
          if (members.includes(userId)) {
            socket.join(`group:${groupId}`);
          }
        }
        
        // 通知好友该用户已上线
        if (friendships.has(userId)) {
          const friends = friendships.get(userId);
          friends.forEach(friendId => {
            io.to(friendId).emit('friend_status_change', { userId, online: true });
          });
        }
        
        // 发送用户数据和未读消息
        socket.emit('login_success', { user: currentUser });
        
        // 发送好友列表
        const friendsList = [];
        if (friendships.has(userId)) {
          const friends = friendships.get(userId);
          friends.forEach(friendId => {
            if (users.has(friendId)) {
              friendsList.push(users.get(friendId));
            }
          });
        }
        socket.emit('friends_list', { friends: friendsList });
        
        // 发送群组列表
        const userGroups = [];
        for (const [groupId, members] of groupMembers.entries()) {
          if (members.includes(userId) && groups.has(groupId)) {
            const group = groups.get(groupId);
            userGroups.push({
              ...group,
              memberCount: members.length
            });
          }
        }
        socket.emit('groups_list', { groups: userGroups });
        
        console.log(`用户 ${userId} 已登录`);
      } else {
        socket.emit('login_error', { message: '用户不存在' });
      }
    });
    
    // 发送私聊消息
    socket.on('send_private_message', ({ receiverId, content }) => {
      if (!currentUser) return;
      
      const senderId = currentUser.id;
      const messageId = Date.now().toString();
      const timestamp = Date.now();
      
      // 确定聊天ID（按字母顺序排序确保唯一性）
      const chatId = [senderId, receiverId].sort().join('_');
      
      // 创建消息对象
      const message = {
        id: messageId,
        sender: senderId,
        receiver: receiverId,
        content,
        timestamp
      };
      
      // 存储消息
      if (!privateChats.has(chatId)) {
        privateChats.set(chatId, []);
      }
      privateChats.get(chatId).push(message);
      
      // 发送给接收者
      io.to(receiverId).emit('new_private_message', message);
      
      // 确认消息已发送
      socket.emit('message_sent', { messageId });
      
      console.log(`私聊消息从 ${senderId} 发送到 ${receiverId}: ${content}`);
    });
    
    // 发送群聊消息
    socket.on('send_group_message', ({ groupId, content }) => {
      if (!currentUser) return;
      
      const senderId = currentUser.id;
      const messageId = Date.now().toString();
      const timestamp = Date.now();
      
      // 检查用户是否在群组中
      if (groupMembers.has(groupId) && groupMembers.get(groupId).includes(senderId)) {
        // 创建消息对象
        const message = {
          id: messageId,
          sender: senderId,
          groupId,
          content,
          timestamp
        };
        
        // 存储消息
        if (!groupChats.has(groupId)) {
          groupChats.set(groupId, []);
        }
        groupChats.get(groupId).push(message);
        
        // 发送给群组所有成员
        io.to(`group:${groupId}`).emit('new_group_message', message);
        
        // 确认消息已发送
        socket.emit('message_sent', { messageId });
        
        console.log(`群聊消息从 ${senderId} 发送到群组 ${groupId}: ${content}`);
      }
    });
    
    // 获取私聊历史消息
    socket.on('get_private_chat_history', ({ userId, friendId }) => {
      if (!currentUser) return;
      
      // 确定聊天ID
      const chatId = [userId, friendId].sort().join('_');
      
      // 获取聊天历史
      const history = privateChats.has(chatId) ? privateChats.get(chatId) : [];
      
      // 发送聊天历史
      socket.emit('private_chat_history', { friendId, messages: history });
    });
    
    // 获取群聊历史消息
    socket.on('get_group_chat_history', ({ groupId }) => {
      if (!currentUser) return;
      
      // 检查用户是否在群组中
      if (groupMembers.has(groupId) && groupMembers.get(groupId).includes(currentUser.id)) {
        // 获取聊天历史
        const history = groupChats.has(groupId) ? groupChats.get(groupId) : [];
        
        // 发送聊天历史
        socket.emit('group_chat_history', { groupId, messages: history });
      }
    });
    
    // 发送好友请求
    socket.on('send_friend_request', ({ targetUserId }) => {
      if (!currentUser) return;
      
      const senderId = currentUser.id;
      
      // 检查目标用户是否存在
      if (users.has(targetUserId)) {
        // 检查是否已经是好友
        if (friendships.has(senderId) && friendships.get(senderId).includes(targetUserId)) {
          socket.emit('friend_request_error', { message: '已经是好友了' });
          return;
        }
        
        // 创建好友请求
        const requestId = `${senderId}_${targetUserId}_${Date.now()}`;
        const request = {
          id: requestId,
          sender: senderId,
          receiver: targetUserId,
          status: 'pending',
          timestamp: Date.now()
        };
        
        // 存储请求
        if (!friendRequests.has(targetUserId)) {
          friendRequests.set(targetUserId, []);
        }
        friendRequests.get(targetUserId).push(request);
        
        // 通知目标用户
        io.to(targetUserId).emit('new_friend_request', {
          request,
          sender: currentUser
        });
        
        // 确认请求已发送
        socket.emit('friend_request_sent', { requestId });
        
        console.log(`好友请求从 ${senderId} 发送到 ${targetUserId}`);
      } else {
        socket.emit('friend_request_error', { message: '用户不存在' });
      }
    });
    
    // 处理好友请求
    socket.on('handle_friend_request', ({ requestId, accept }) => {
      if (!currentUser) return;
      
      const userId = currentUser.id;
      
      // 查找请求
      let request = null;
      let requestIndex = -1;
      
      if (friendRequests.has(userId)) {
        const requests = friendRequests.get(userId);
        requestIndex = requests.findIndex(req => req.id === requestId);
        
        if (requestIndex !== -1) {
          request = requests[requestIndex];
        }
      }
      
      if (request) {
        // 更新请求状态
        request.status = accept ? 'accepted' : 'rejected';
        
        // 如果接受请求，建立好友关系
        if (accept) {
          const senderId = request.sender;
          
          // 添加好友关系
          if (!friendships.has(userId)) friendships.set(userId, []);
          if (!friendships.has(senderId)) friendships.set(senderId, []);
          
          friendships.get(userId).push(senderId);
          friendships.get(senderId).push(userId);
          
          // 通知发送者请求已接受
          io.to(senderId).emit('friend_request_accepted', {
            requestId,
            friend: currentUser
          });
          
          // 通知接收者好友已添加
          socket.emit('friend_added', {
            friend: users.get(senderId)
          });
          
          console.log(`${userId} 接受了 ${senderId} 的好友请求`);
        } else {
          // 通知发送者请求已拒绝
          io.to(request.sender).emit('friend_request_rejected', { requestId });
          console.log(`${userId} 拒绝了 ${request.sender} 的好友请求`);
        }
        
        // 从请求列表中移除
        if (friendRequests.has(userId)) {
          const requests = friendRequests.get(userId);
          requests.splice(requestIndex, 1);
        }
      }
    });
    
    // 创建群组
    socket.on('create_group', ({ groupName, members }) => {
      if (!currentUser) return;
      
      const creatorId = currentUser.id;
      const groupId = `group_${Date.now()}`;
      
      // 创建群组
      const group = {
        id: groupId,
        name: groupName,
        avatar: '/avatars/avatar2.svg', // 默认头像
        createdBy: creatorId,
        createdAt: Date.now()
      };
      
      // 存储群组信息
      groups.set(groupId, group);
      
      // 添加成员（确保创建者也是成员）
      const allMembers = [...new Set([creatorId, ...members])];
      groupMembers.set(groupId, allMembers);
      
      // 将创建者加入群组房间
      socket.join(`group:${groupId}`);
      
      // 通知所有成员
      allMembers.forEach(memberId => {
        if (users.has(memberId)) {
          io.to(memberId).emit('group_created', {
            group: {
              ...group,
              memberCount: allMembers.length
            }
          });
          
          // 将在线成员加入群组房间
          const member = users.get(memberId);
          if (member.online && member.socketId) {
            const memberSocket = io.sockets.sockets.get(member.socketId);
            if (memberSocket) {
              memberSocket.join(`group:${groupId}`);
            }
          }
        }
      });
      
      console.log(`${creatorId} 创建了群组 ${groupName} (${groupId})`);
    });
    
    // 获取群组成员
    socket.on('get_group_members', ({ groupId }) => {
      if (!currentUser) return;
      
      // 检查群组是否存在且用户是否是成员
      if (groups.has(groupId) && 
          groupMembers.has(groupId) && 
          groupMembers.get(groupId).includes(currentUser.id)) {
        
        const memberIds = groupMembers.get(groupId);
        const members = memberIds.map(id => users.has(id) ? users.get(id) : null).filter(Boolean);
        
        socket.emit('group_members', { groupId, members });
      }
    });
    
    // 用户断开连接
    socket.on('disconnect', () => {
      if (currentUser) {
        currentUser.online = false;
        delete currentUser.socketId;
        
        // 通知好友该用户已下线
        if (friendships.has(currentUser.id)) {
          const friends = friendships.get(currentUser.id);
          friends.forEach(friendId => {
            io.to(friendId).emit('friend_status_change', { userId: currentUser.id, online: false });
          });
        }
        
        console.log(`用户 ${currentUser.id} 已断开连接`);
      }
      console.log('用户已断开连接:', socket.id);
    });
  });
  
  // 处理所有HTTP请求
  // app.all('*', (req, res) => {
  //   return nextHandler(req, res);
  // });
  app.use((req, res) => nextHandler(req, res));
  
  server.listen(port, host, (err) => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${port}`);
  });
});